package org.lld.im.service.config;

import org.I0Itec.zkclient.ZkClient;
import org.lld.im.common.config.AppConfig;
import org.lld.im.common.enums.ImUrlRouteWayEnum;
import org.lld.im.common.enums.RouteHashMethodEnum;
import org.lld.im.common.route.RouteHandler;
import org.lld.im.common.route.algorithm.consistenthash.AbstractConsistentHash;
import org.lld.im.service.utils.SnowflakeIdWorker;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.lang.reflect.Method;

/**
 * @author: LunBoWang
 * @description: bean配置类
 * @date: 2025/3/30 下午7:29
 * @version: 1.0
 */
@Configuration
public class BeanConfig {
    @Resource
    AppConfig appConfig;

    @Bean
    public ZkClient bulidZkClient() {
        return new ZkClient(appConfig.getZkAddr(), appConfig.getZkConnectTimeOut());
    }

    @Bean
    public RouteHandler routeHandle() throws Exception {
        // 从配置中获取路由方式
        Integer imRouteWay = appConfig.getImRouteWay();
        String routeWay = "";
        // 通过枚举获取对应的路由处理器类名
        ImUrlRouteWayEnum handler = ImUrlRouteWayEnum.getHandler(imRouteWay);
        routeWay = handler.getClazz();
        // 反射创建路由处理器实例
        RouteHandler routeHandler = (RouteHandler) Class.forName(routeWay).newInstance();
        // 如果是哈希路由方式，需要额外配置哈希算法
        if (handler == ImUrlRouteWayEnum.HASH) {
            // 获取setHash方法用于注入哈希算法
            Method setHash = Class.forName(routeWay).getMethod("setHash", AbstractConsistentHash.class);
            // 从配置获取哈希算法类型
            Integer consistentHashWay = appConfig.getConsistentHashWay();
            String hashWay = "";
            // 通过枚举获取对应的哈希算法类名
            RouteHashMethodEnum hashHandler = RouteHashMethodEnum.getHandler(consistentHashWay);
            hashWay = hashHandler.getClazz();
            // 反射创建哈希算法实例
            AbstractConsistentHash consistentHash = (AbstractConsistentHash) Class.forName(hashWay).newInstance();
            // 将哈希算法注入路由处理器
            setHash.invoke(routeHandler, consistentHash);
        }
        return routeHandler;
    }

    @Bean
    public EasySqlInjector easySqlInjector() throws Exception {
        return new EasySqlInjector();
    }

    @Bean
    public SnowflakeIdWorker buildSnowflackeSeq() throws Exception {
        return new SnowflakeIdWorker(0);
    }
}
